package com.yykj.drup.server.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.gson.Gson;
import com.kuaidi100.sdk.api.QueryTrack;
import com.kuaidi100.sdk.api.Subscribe;
import com.kuaidi100.sdk.contant.ApiInfoConstant;
import com.kuaidi100.sdk.core.IBaseClient;
import com.kuaidi100.sdk.pojo.HttpResult;
import com.kuaidi100.sdk.request.*;
import com.kuaidi100.sdk.response.QueryTrackData;
import com.kuaidi100.sdk.response.QueryTrackMapResp;
import com.kuaidi100.sdk.response.SubscribePushData;
import com.kuaidi100.sdk.response.SubscribePushResult;
import com.kuaidi100.sdk.utils.SignUtils;
import com.yykj.drup.server.config.KuaiDiAccountConfig;
import com.yykj.drup.server.model.ExpressContext;
import com.yykj.drup.server.service.ExpressContextService;
import com.yykj.drup.server.service.ExpressService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @Author zeng
 * @Date 2022/3/29
 */
@Service
@Slf4j
public class ExpressServiceImpl implements ExpressService {

    @Autowired
    ExpressContextService contextService;

    /**
     * 订阅回调地址
     */
    @Value("${kuaidi.callBackUrl}")
    private String callBackUrl;

    @Override
    public List<QueryTrackData> pollKuaidi(String com, String num) {
        QueryTrackReq queryTrackReq = new QueryTrackReq();
        QueryTrackParam queryTrackParam = new QueryTrackParam();
        queryTrackParam.setCom(com);
        queryTrackParam.setNum(num);
        queryTrackParam.setResultv2("2");
        String param = new Gson().toJson(queryTrackParam);
        queryTrackReq.setParam(param);
        queryTrackReq.setCustomer(KuaiDiAccountConfig.customer);
        queryTrackReq.setSign(SignUtils.querySign(param ,KuaiDiAccountConfig.key,KuaiDiAccountConfig.customer));
        IBaseClient baseClient = new QueryTrack();
        HttpResult result = null;
        try {
            result = baseClient.execute(queryTrackReq);
        } catch (Exception e) {
            e.printStackTrace();
        }
        QueryTrackMapResp queryTrackMapResp = new Gson().fromJson(result.getBody(),QueryTrackMapResp.class);
        System.out.println(queryTrackMapResp.getData());
        return queryTrackMapResp.getData();
    }

    @Override
    public HttpResult expressPoll(String number,String phone,String company) {

        SubscribeParameters subscribeParameters = new SubscribeParameters();
        //设置签名 签名用随机字符串。32位自定义字符串。添加该参数，则推送的时候会增加sign给贵司校验消息的可靠性
        subscribeParameters.setSalt(KuaiDiAccountConfig.userid);
        subscribeParameters.setCallbackurl(callBackUrl);
        subscribeParameters.setPhone(phone);
        subscribeParameters.setResultv2("1");
        if (StrUtil.isEmpty(company)){
            subscribeParameters.setAutoCom("1");
        }
        SubscribeParam subscribeParam = new SubscribeParam();
        subscribeParam.setParameters(subscribeParameters);
        subscribeParam.setCompany(company);
        subscribeParam.setNumber(number);
        subscribeParam.setKey(KuaiDiAccountConfig.key);

        SubscribeReq subscribeReq = new SubscribeReq();
        subscribeReq.setSchema(ApiInfoConstant.SUBSCRIBE_SCHEMA);
        subscribeReq.setParam(new Gson().toJson(subscribeParam));

        IBaseClient subscribe = new Subscribe();
        try {
            log.info("发起物流消息订阅请求开始，参数为：{}",subscribeParam);
            HttpResult execute = subscribe.execute(subscribeReq);
            log.info("发起物流消息订阅请求结束，接收数据为：{}",execute);
            switch (Integer.valueOf(execute.getStatus())){
                case 500:
                    throw new RuntimeException("服务器错误");
                case 501:
                    throw new RuntimeException("重复订阅");
                case 502:
                    throw new RuntimeException("提交内容含有敏感关键字，被安全防护拦截");
                case 600:
                    throw new RuntimeException("您不是合法的订阅者（即授权Key出错）");
                case 601:
                    throw new RuntimeException("POLL: KEY 已过期");
                case 700:
                    throw new RuntimeException("不支持的快递公司");
                case 701:
                    throw new RuntimeException("订阅方的订阅数据存在错误（如不支持的快递公司、单号为空、单号超长等）或错误的回调地址");
                case 702:
                    throw new RuntimeException("POLL:识别不到该单号对应的快递公司");
            }
            return execute;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("发起物流消息订阅请求异常");
        }
    }

    @Override
    public void insertExpressContext(SubscribePushResult lastResult) {

        List<SubscribePushData> dataList = lastResult.getData();
        dataList.stream().forEach(data -> {
            LambdaQueryWrapper<ExpressContext> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ExpressContext::getOrderComNumber,lastResult.getNu())
                    .eq(ExpressContext::getFtime,data.getFtime());
            if (contextService.list(wrapper).isEmpty()){
                ExpressContext context = new ExpressContext();
                BeanUtil.copyProperties(data,context);
                context.setOrderComNumber(lastResult.getNu());
                contextService.save(context);
            }
        });
    }

    @Override
    public void insertExpressContextQueryTrackData(String expressNo) {
        List<QueryTrackData> queryTrackData = this.pollKuaidi(null, expressNo);
        queryTrackData.stream().forEach(data -> {
                ExpressContext context = new ExpressContext();
                BeanUtil.copyProperties(data,context);
                context.setOrderComNumber(expressNo);
                contextService.save(context);
        });
    }
}
